#pragma once

#include <iostream>
namespace self
{
	class string
	{
		typedef char* iterator;
		typedef const char* const_iterator;
	public:
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}

		const_iterator begin() const
		{
			return _str;
		}
		const_iterator end() const
		{
			return _str + _size;
		}

		string(const char* str = "")
		{
			size_t len = strlen(str);
			_size = _capacity = len;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		string(const string& s)
		{
			string tmp(s._str);
			swap(tmp);
		}

		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}


		char& operator[](size_t n)
		{
			return _str[n];
		}
		const char& operator[](size_t n) const
		{
			return _str[n];
		}

		string& operator=(string s)
		{
			swap(s);
			return *this;
		}

		bool operator==(const string& s)
		{
			return strcmp(_str, s._str) == 0;
		}

		bool operator<(const string& s)
		{
			return strcmp(_str, s._str) < 0;
		}

		bool operator>(const string& s)
		{
			return strcmp(_str, s._str) > 0;
		}

		bool operator>=(const string& s)
		{
			return !(strcmp(_str, s._str) < 0);
		}

		friend std::ostream& operator<<(std::ostream& out, const string& s);
	private:
		char* _str = nullptr;
		size_t _size = 0;
		size_t _capacity = 0;
	};

	std::ostream& operator<<(std::ostream& out, const string& s)
	{
		for (int i = 0; i < s._size; i++)
		{
			out << s[i];
		}
		return out;
	}



}
